import paho.mqtt.client as mqtt
import time
import logging
import json
import threading
import base64
import cv2
import time
import subprocess
from aip import AipFace
from unihiker import GUI
from aip import AipSpeech
from aip import AipBodyAnalysis
from aip import AipImageClassify


class RobotMQTTClient:
    def __init__(self, broker, port, username, password):
        self.broker = broker
        self.port = port
        self.username = username
        self.password = password
        self.camera_image_base64 = ""
        self.count = 0
        self.running = False

        # 日志配置
        logging.basicConfig(level=logging.INFO)
        self.logger = logging.getLogger("MQTT_Client")

        # 初始化客户端
        self.client = mqtt.Client()
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.on_disconnect = self.on_disconnect

        if self.username and self.password:
            self.client.username_pw_set(self.username, self.password)

    def set_camera_image(self, base64_str):
        """设置相机图像的Base64数据"""
        self.camera_image_base64 = base64_str

    def on_connect(self, client, userdata, flags, rc):
        if rc == 0:
            self.logger.info("✅ 连接成功！")
            client.subscribe("robot/hexapod/status")
        else:
            self.logger.error(f"❌ 连接失败！错误码: {rc}")

    def on_message(self, client, userdata, msg):
        try:
            payload = json.loads(msg.payload.decode())
            self.logger.info(f"📩 收到命令 [{msg.topic}]: {json.dumps(payload, indent=2)}")
        except:
            self.logger.info(f"📩 收到消息 [{msg.topic}]: {msg.payload.decode()}")

    def on_disconnect(self, client, userdata, rc):
        if rc != 0:
            self.logger.warning("⚠️ 意外断开连接，尝试重连...")
            try:
                client.reconnect()
            except Exception as e:
                self.logger.error(f"重连失败: {str(e)}")

    def publish_status(self):
        """发布机器人状态信息"""
        status = {
            "robot_id": "xxxx",
            "timestamp": 1,
            "location": {
                "latitude": 1,
                "longitude": 1,
                "altitude": 1
            },
            "orientation": {
                "roll": 1,
                "pitch": 1,
                "yaw": 1
            },
            "battery_level": 1,
            "sensors": {
                "temperature": 1,
                "humidity": 1,
                "gas_detection": {
                    "CO": 1,
                    "CH4": 1
                }
            },
            "status": "exploring",
            "person_detected": True,
            "person_count": 1,
            "detection_confidence": 1,
            "person_locations": [
                {"x": 1, "y": 1, "confidence": 1},
                {"x": 1, "y": 11, "confidence": 1}
            ],
            "camera_image": f"data:image/jpeg;base64,{self.camera_image_base64}"
        }

        payload = json.dumps(status)
        result = self.client.publish("robot/hexapod/status", payload, qos=1)

        if result.rc == mqtt.MQTT_ERR_SUCCESS:
            self.logger.info(f"📤 状态已发送 (电池: {status['battery_level']}%, 航向: {status['orientation']['yaw']}°)")
        else:
            self.logger.error(f"发送失败！错误码: {result.rc}")

        self.count += 1

    def start(self):
        """启动MQTT客户端"""
        try:
            self.client.connect(self.broker, self.port, keepalive=60)
            self.logger.info(f"🔌 正在连接 {self.broker}:{self.port}...")
            self.client.loop_start()
            self.running = True

            def publish_loop():
                self.publish_status()
                time.sleep(3)

            threading.Thread(target=publish_loop, daemon=True).start()

        except Exception as e:
            self.logger.error(f"‼️ 发生异常: {str(e)}")
            self.stop()

    def stop(self):
        """停止MQTT客户端"""
        self.running = False
        self.client.disconnect()
        self.client.loop_stop()
        self.logger.info("⛔ 已断开连接")


def image_to_base64(image_path):
    """将图片转换为Base64字符串[6,7,8](@ref)"""
    try:
        with open(image_path, "rb") as image_file:
            encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
            return encoded_string
    except Exception as e:
        print(f"图片转换失败: {str(e)}")
        return ""


def readImage(src):
    try:
        with open(src, "rb") as f:
            return f.read()
    except FileNotFoundError as e:
        print(f"[文件不存在] {e}")
        return None
    except TypeError as e:
        print(f"[输入类型异常] {e}")
        return None
    except BaseException as e:
        print(f"[通用异常] {e}")
        return None


def advancedGeneral_705():
    aip_advancedGeneral_result = aip_img_client.advancedGeneral(readImage("recognition.png"))
    if len(aip_advancedGeneral_result["result"]) > 0:
        _keywords = aip_advancedGeneral_result["result"]
        keywords = set()
        for item in _keywords:
            keywords.add(item["keyword"])
        return keywords
    else:
        print("Insufficient quantity identified")
        return ""


def advancedGeneral_705():
    aip_advancedGeneral_result = aip_img_client.advancedGeneral(readImage("recognition.png"))
    if len(aip_advancedGeneral_result["result"]) > 0:
        _keywords = aip_advancedGeneral_result["result"]
        keywords = set()
        for item in _keywords:
            keywords.add(item["keyword"])
        return keywords
    else:
        print("Insufficient quantity identified")
        return ""


def pngquant_compress(input_path, output_path, quality="65-80"):
    cmd = ["pngquant", "--quality", quality, "--force", "--output", output_path, input_path]
    subprocess.run(cmd, check=True)


if __name__ == "__main__":
    mqtt_client = RobotMQTTClient(
        broker="xxx.xxx.xxx.xxx",
        port='xxxx',
        username="xxxx",
        password="xxxxx"
    )

    u_gui = GUI()
    aip_img_client = AipImageClassify("xxxx", "xxxx", "xxx")
    aip_anyalysis_client = AipBodyAnalysis("xxxx", "xxxx", "xxx")
    aip_face_client = AipFace("xxxx", "xxxx", "xxxx")
    aip_speech_client = AipSpeech("xxxx", "xxxx", "xxxxx")
    test = u_gui.draw_text(text="xxxx", x=5, y=5, font_size=20, color="#0000FF")
    vd = cv2.VideoCapture()
    vd.open(0)
    cv2.namedWindow("Mind+'s Windows", cv2.WINDOW_NORMAL)
    cv2.setWindowProperty("Mind+'s Windows", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
    plist = {}
    while True:
        ret, img = vd.read()
        outImg = cv2.resize(img, (240, 320))
        cv2.imshow("xx", outImg)
        cv2.imwrite("x.png", outImg)
        txsblist = advancedGeneral_705()
        print(txsblist)
        txsblist.intersection_update(plist)
        print(len(txsblist))
        if len(txsblist) >= 1:
            #             pngquant_compress("recognition.png", "output.png", quality="65-80")
            image_base64 = image_to_base64("x.png")
            if not image_base64:
                print("无法获取图片数据，程序终止")
                exit()

            mqtt_client.set_camera_image(image_base64)

            mqtt_client.start()
            time.sleep(10)

    vd.release()
    cv2.destroyAllWindows()
